package com.yanqu.road.factory;

import com.yanqu.road.define.YanQuSslDefine;

import java.security.KeyStore;

import javax.net.ssl.KeyManagerFactory;
import javax.net.ssl.SSLContext;
import javax.net.ssl.TrustManagerFactory;

public class SslContextFactory {
	private static final String PROTOCOL = "TLS";
	private static final SSLContext	SERVER_CONTEXT;
	private static final SSLContext	CLIENT_CONTEXT;

	static {

		SSLContext serverContext;
		SSLContext clientContext;

		String keyStorePassword = YanQuSslDefine.KEY_STORE_PASSWORD;
		serverContext = getServerSslContext("JKS", keyStorePassword);
		clientContext = getClientSslContext("JKS", keyStorePassword);

		SERVER_CONTEXT = serverContext;
		CLIENT_CONTEXT = clientContext;
	}

	private static SSLContext getServerSslContext(String type, String keyStorePassword) {
		SSLContext serverContext;
		try {
			KeyStore ks = KeyStore.getInstance(type);
			ks.load(SslContextFactory.class.getClassLoader().getResourceAsStream(YanQuSslDefine.SERVER_KEY_STORE_NAME),
					keyStorePassword.toCharArray());

			KeyManagerFactory kmf = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm());
			kmf.init(ks, keyStorePassword.toCharArray());


			KeyStore ts = KeyStore.getInstance(type);
			ts.load(SslContextFactory.class.getClassLoader().getResourceAsStream(YanQuSslDefine.SERVER_TRUST_KEY_STORE_NAME),
					keyStorePassword.toCharArray());

			TrustManagerFactory tmf = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
			tmf.init(ts);


			serverContext = SSLContext.getInstance(PROTOCOL);
			serverContext.init(kmf.getKeyManagers(), tmf.getTrustManagers(), null);

		} catch (Exception e) {
			throw new Error("init server side ssl context fail:", e);
		}
		return serverContext;
	}

	private static SSLContext getClientSslContext(String type, String keyStorePassword) {
		SSLContext clientContext;
		try {
			KeyStore ks = KeyStore.getInstance(type);
			ks.load(SslContextFactory.class.getClassLoader().getResourceAsStream(YanQuSslDefine.CLIENT_KEY_STORE_NAME),
					keyStorePassword.toCharArray());

			KeyManagerFactory kmf = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm());
			kmf.init(ks, keyStorePassword.toCharArray());

			KeyStore ts = KeyStore.getInstance(type);
			ts.load(SslContextFactory.class.getClassLoader().getResourceAsStream(YanQuSslDefine.CLIENT_TRUST_KEY_STORE_NAME),
					keyStorePassword.toCharArray());

			TrustManagerFactory tmf = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
			tmf.init(ts);
			clientContext = SSLContext.getInstance(PROTOCOL);
			clientContext.init(kmf.getKeyManagers(), tmf.getTrustManagers(), null);
		} catch (Exception e) {
			throw new Error("init client side ssl context fail:", e);
		}
		return clientContext;
	}



	public static SSLContext getServerContext()
	{
		return SERVER_CONTEXT;
	}

	public static SSLContext getClientContext()
	{
		return CLIENT_CONTEXT;
	}

	private SslContextFactory() {

	}
}
